#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <cstdio>
#include <string>
#include <vector>
#include <memory>
#include "Thread.hpp"
#include "Mutex.hpp"
using namespace std;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;q
int ticket = 10000;

class ThreadData
{
public:
    ThreadData(const string& name = "", pthread_mutex_t* mutex_p = nullptr) :name_(name) ,mutex_p_(mutex_p)
    {}
public:
    std::string name_;
    pthread_mutex_t* mutex_p_;
};


void* start_routine(void* args)
{   
    //string name = static_cast<const char*>(args);
    ThreadData* td = static_cast<ThreadData*>(args);

    while(1)
    {
        
        //pthread_mutex_lock(&lock);
        //pthread_mutex_lock(td->mutex_p_);
        //模拟c++ARRI
        {
            LockGuard lg(&lock);
            if(ticket > 0)
            {
            usleep(1234);  
            //cout << name << " 正在抢票" << " ticket: " << ticket << endl;
            cout << td->name_ << " 正在抢票" << " ticket: " << ticket << endl;

            ticket--;
            //pthread_mutex_unlock(&lock);
            //pthread_mutex_unlock(td->mutex_p_);

            }
            else
            {
                //pthread_mutex_unlock(&lock);
                //pthread_mutex_unlock(td->mutex_p_);
                break;
            }
        }
        usleep(100);
    }
    return nullptr;
}
int main()
{

#define NUM 4
    pthread_mutex_t lock;
    pthread_mutex_init(&lock, nullptr);
    vector<pthread_t> tids(NUM);
    vector<ThreadData> tds(NUM);
    for(int i = 0; i < NUM; ++i)
    {
        char buffer[64];
        snprintf(buffer, sizeof buffer, "thread %d", i + 1);
        tds[i] = ThreadData(buffer, &lock);
        //ThreadData* td = new ThreadData(buffer, &lock);
        pthread_create(&tids[i], nullptr, start_routine, (void*)&tds[i]);
    }

    for(const auto& tid : tids)
    {
        pthread_join(tid, nullptr);
    }
    pthread_mutex_destroy(&lock);



    // pthread_mutex_t lock;
    // pthread_mutex_init(&lock, nullptr);
    // pthread_t t1, t2, t3, t4;
    // pthread_create(&t1, nullptr, start_routine, (void*)"thread one");
    // pthread_create(&t2, nullptr, start_routine, (void*)"thread two");
    // pthread_create(&t3, nullptr, start_routine, (void*)"thread three");
    // pthread_create(&t4, nullptr, start_routine, (void*)"thread four");


    // pthread_join(t1, nullptr);
    // pthread_join(t2, nullptr);
    // pthread_join(t3, nullptr);
    // pthread_join(t4, nullptr);
    // pthread_mutex_destroy(&lock);




    // shared_ptr<Thread> thread1(new Thread(start_routine, (void*)"user1", 1));
    // shared_ptr<Thread> thread2(new Thread(start_routine, (void*)"user1", 2));
    // shared_ptr<Thread> thread3(new Thread(start_routine, (void*)"user1", 3));

    // thread1->join();
    // thread2->join();
    // thread3->join();

    
    return 0;
}